/********************************************************************************
 * Copyright (c)2016-2020, ShenZhen WanJiaAn Technology CO.,LTD.
 * All Rights Reserved.
 *
 * File Name     : Upgrade.c
 * Author        : joki.zhu
 * Date          : 2019-11-07
 *
 * Record        :
 * 1.Date        : 2019-11-07
 *   Author      : joki.zhu
 *   Modification: Created file
 ********************************************************************************/
#include "Upgrade.h"
#include "hi_upgrade.h"
#include "app_common.h"
#include "PowerManager.h"
#include "DevLed.h"
#include "Video.h"
#include "OsdDraw.h"
#include "DevSocSub.h"
#include "UpgradeRecovery.h"
#include "System.h"

#ifdef YD_PROTOCOL
#include "DOTHejiaguhua.h"
#endif /* YD_PROTOCOL */

static char bInit = 0;
static char bRun = 0;

int UpgradeInit(int pktSize)
{
    if (PowerCheckIsSleeping()) {
        LOGW("sleep is sleeping...\n");
        return -1;
    }
    
    BATTERY_STATUS_S stBatStatus;
    memset(&stBatStatus, 0, sizeof(stBatStatus));
    SocSubGetBatteryStatus(&stBatStatus);
    if (stBatStatus.capacity < 30 && stBatStatus.chargingStatus == BAT_DISCHARGING) {
        LOGW("!!! capacity:%d battery capacity less than 30/100 !!!!\n", stBatStatus.capacity);
        return -1;
    }

    UpgradeRecoverySetState(1);

    if (bInit == 0)
    {
        /* set power keepalive time */
        PowerSetSocSleepTime(AV_TRUE, 3 * 60);
        bRun = 1;
        
        LedSet(LED_TYPE_BLUE, LED_STATE_UPGRADE, LED_LEVEL_HIGH);

#ifdef SOSUB_WDG_ENABLE
        /* close mcu wdt */
        SocSubSetWdgState(0);
#endif /* SOCSUB_WDG_ENABLE */

#ifdef YD_PROTOCOL
#ifndef MINI_APP
        DOTSetHandUp();
        LOGW("CDestroyEngine() begin\n");
        DOTHejiaguhuaDeInit();
#endif /* MINI_APP */
        SYSTEM_INFO_S stSysInfo;
        memset(&stSysInfo, 0, sizeof(stSysInfo));
        SystemGetSysInfo(&stSysInfo);
        LOGI("uwFreeMem==========%u\n", stSysInfo.freeMemSize);

        DevSetPackTime("1"); // support same pkt to upgrade again
#endif /* YD_PROTOCOL */

#ifndef MINI_APP
        /* free osd resource */
        OsdDrawDeinit();

        /* free video resource */
        HalVideoDeInit();
#endif /* MINI_APP */

        /* set ramfs size */
        los_set_ramfs_unit(AV_ALIGN_UP(pktSize, 0x10000));

        bInit = 1;
        
        LOGI("Upgrade init ok pktSize %d\n", pktSize);
    }
    
    return 0;
}

int UpgradeRun(char *pktPath)
{
    if (pktPath == NULL) {
        LOGE("pktPath is NULL\n");
        return -1;
    }

    int ret = 0;
    char devSoftVersion[32] = {0};
    char devSoftTime[32] = {0};
    HI_UPGRADE_DEV_INFO_S devInfo;

    /* set system power keepalive lock */
    PowerSetWakeLock("upgrade");

    LedSet(LED_TYPE_RED, LED_STATE_UPGRADE, LED_LEVEL_HIGH);
    LOGI("Upgrade is running [pktPath:%s]\n", pktPath);
    
    memset(&devInfo, 0, sizeof(devInfo));
    DevGetSoftVersion(devSoftVersion);
    sprintf(devInfo.szSoftVersion, "%s", devSoftVersion);

    DevGetPackTime(devSoftTime);
    sprintf(devInfo.szSoftTime, "%s", devSoftTime);   

    ret = HI_UPGRADE_CheckPkt(pktPath, &devInfo);
    if (ret < 0) {
        PowerSetWakeUnLock("upgrade");
        LOGE("HI_UPGRADE_CheckPkt failed\n");
#ifdef YD_PROTOCOL
        SystemReboot("upgrade crc is error, reboot to recovery upgrade");
#endif /* YD_PROTOCOL */
        return -1;
    }
    
    ret = HI_UPGRADE_DoUpgrade(pktPath);
    if (ret < 0) {
        LOGE("HI_UPGRADE_DoUpgrade failed\n");
        return -1;
    }

    LOGI("Upgrade ok\n");
    
    return 0;
}

int UpgradeDeinit()
{
    /* recovery ramfs size */
    los_set_ramfs_unit(0);

    /* set system power keepalive unlock */
    PowerSetWakeUnLock("upgrade");

    LOGI("Upgrade deinit ok\n");
    UpgradeRecoverySetState(0);
	UpgradeRecoverySetRetryCnt(0);
    
    LedSet(LED_TYPE_NONE, LED_STATE_NONE, LED_LEVEL_HIGH);

    bInit = 0;
    bRun = 0;
    
    return 0;
}

/**
 * @brief 检查是否正在升级
 *
 * @param 无
 * 
 * @return |0|未升级| |1|正在升级|
 *
 * @attention 无
 */
int UpgradeCheckIsRun(void)
{
    return bRun;
}
